package tehUtils;

import java.util.ArrayList;
import java.util.Random;

import net.minecraft.src.AxisAlignedBB;
import net.minecraft.src.Block;
import net.minecraft.src.Entity;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.ItemStack;
import net.minecraft.src.Material;
import net.minecraft.src.TileEntity;
import net.minecraft.src.Vec3D;
import net.minecraft.src.World;
import net.minecraft.src.ModLoader;

/**
 * @author TehJoe
 * 
 *  A simple class that represents a block at a specific position.
 *  It supplies a version of most World/Block methods that no longer
 *  require passing the block's position every time they are called. 
 */

public class BlockInstance {
	
	private World worldObj;
	
	public int posX;
	public int posY;
	public int posZ;
	
	public Block block;
	public int blockID;
	public int metadata;
	
	/**
	 * @param x The X position of the block
	 * @param y The Y position of the block
	 * @param z The Z position of the block
	 */
	public BlockInstance(int x, int y, int z) {
		worldObj = ModLoader.getMinecraftInstance().theWorld;
		
		posX = x;
		posY = y;
		posZ = z;
		
		blockID = worldObj.getBlockId(x, y, z);
		metadata = worldObj.getBlockMetadata(x, y, z);
		block = Block.blocksList[blockID];
	}

    public boolean isOpaqueCube() {
    	return worldObj.isBlockOpaqueCube(posX, posY, posZ);
    }

    public boolean isNormalCube() {
    	return worldObj.isBlockNormalCube(posX, posY, posZ);
    }

    public boolean isAir() {
    	return worldObj.isAirBlock(posX, posY, posZ);
    }
    
    public boolean isGettingPowered() {
    	return worldObj.isBlockGettingPowered(posX, posY, posZ);
    }
        
    public boolean isIndirectlyGettingPowered() {
    	return worldObj.isBlockIndirectlyGettingPowered(posX, posY, posZ);
    }
    
    public boolean isProvidingPowerTo() {
    	return block.isPoweringTo(worldObj, posX, posY, posZ, metadata);
    }
    
    public boolean isIndirectlyProvidingPowerTo(int x, int y, int z) {
    	return block.isIndirectlyPoweringTo(worldObj, posX, posY, posZ, metadata);
    }
    
    public boolean isSolid() {
    	return block.isBlockSolid(worldObj, posX, posY, posZ, metadata);
    }
    
    public boolean isSolidOnSide(int side) {
    	return worldObj.isBlockSolidOnSide(posX, posY, posZ, side);
    }
    
    public boolean canStay() {
    	return block.canBlockStay(worldObj, posX, posY, posZ);
    }
    
    public boolean canHarvest(EntityPlayer player) {
    	return block.canHarvestBlock(player, metadata);
    }
    
    public boolean hasTileEntity() {
    	return block.hasTileEntity(metadata);
    }
    
    public boolean isBurning() {
    	return block.isBlockBurning(worldObj, posX, posY, posZ);
    }
    
    public boolean isReplaceable() {
    	return block.isBlockReplaceable(worldObj, posX, posY, posZ);
    }
    
    public boolean isFireSource(int face) {
    	return block.isFireSource(worldObj, posX, posY, posZ, metadata, face);
    }
    
    public boolean shouldSideBeRendered(int side) {
    	return block.shouldSideBeRendered(worldObj, posX, posY, posZ, side);
    }
    
    public boolean isLadder() {
    	return block.isLadder(worldObj, posX, posY, posZ);
    }
    
    public int getTexture() {
    	return block.getBlockTexture(worldObj, posX, posY, posZ, metadata);
    }
    
    public int getTextureFromSide(int side) {
    	return block.getBlockTextureFromSide(side);
    }
    
    public int getTextureFromSideAndMetadata(int side, int metadata) {
    	return block.getBlockTextureFromSideAndMetadata(side, metadata);
    }
    
    public int getFireSpreadSpeed(int face) {
    	return block.getFireSpreadSpeed(worldObj, posX, posY, posZ, metadata, face);
    }
    
    public int getFlammability(int face) {
    	return block.getFlammability(worldObj, posX, posY, posZ, metadata, face);
    }
    
    public int getLightValueInt() {
    	return block.getLightValue(worldObj, posX, posY, posZ);
    }
    
    public int getMixedBrightnessForBlock() {
    	return block.getMixedBrightnessForBlock(worldObj, posX, posY, posZ);
    }
    
    public int quantityDropped(Random random) {
    	return block.quantityDropped(random);
    }
    
    public int quantityDropped(int fortune, Random random) {
    	return block.quantityDropped(metadata, fortune, random);
    }
    
    public float getBrightness() {
    	return worldObj.getBrightness(posX, posY, posZ, metadata);
    }

    public float getLightBrightness() {
    	return worldObj.getLightBrightness(posX, posY, posZ);
    }
    
    public float getLightValue() {
    	return worldObj.getBlockLightValue(posX, posY, posZ);
    }
    
    public float getAmbientOcclusionLightValue() {
    	return block.getAmbientOcclusionLightValue(worldObj, posX, posY, posZ);
    }
    
    public float getStrength(EntityPlayer player) {
    	return block.blockStrength(player, metadata);
    }
    
    public ArrayList<ItemStack> getBlockDropped(int fortune) {
    	return block.getBlockDropped(worldObj, posX, posY, posZ, metadata, fortune);
    }
    
    public TileEntity getTileEntity() {
    	return worldObj.getBlockTileEntity(posX, posY, posZ);
    }

    public Material getMaterial() {
    	return worldObj.getBlockMaterial(posX, posY, posZ);
    }
    
    public AxisAlignedBB getCollisionBoundingBoxFromPool() {
    	return block.getCollisionBoundingBoxFromPool(worldObj, posX, posY, posZ);
    }
    
    public void dropAsItem(int fortune) {
    	block.dropBlockAsItem(worldObj, posX, posY, posZ, metadata, fortune);
    }
    
    public void dropAsItemWithChance(float chance, int fortune) {
    	block.dropBlockAsItemWithChance(worldObj, posX, posY, posZ, metadata, chance, fortune);
    }
    
    public void harvest(EntityPlayer player) {
    	block.harvestBlock(worldObj, player, posX, posY, posZ, metadata);
    }
    
    public void setBoundsBasedOnState() {
    	block.setBlockBoundsBasedOnState(worldObj, posX, posY, posZ);
    }
    
    public void velocityToAddToEntity(Entity entity, Vec3D velocity) {
    	block.velocityToAddToEntity(worldObj, posX, posY, posZ, entity, velocity);
    }
    
    public void setBlock(int newBlockID) {
    	worldObj.setBlockWithNotify(posX, posY, posZ, newBlockID);
    	blockID = newBlockID;
    	block = Block.blocksList[blockID];
    	metadata = worldObj.getBlockMetadata(posX, posY, posZ);
    }
    
    public void setBlock(int newBlockID, int newMeta) {
    	worldObj.setBlockAndMetadataWithNotify(posX, posY, posZ, newBlockID, newMeta);
    	blockID = newBlockID;
    	block = Block.blocksList[blockID];
    	metadata = newMeta;
    }
    
    public void setMetadata(int newMeta) {
    	worldObj.setBlockMetadata(posX, posY, posZ, newMeta);
    	metadata = newMeta;
    }
}
